using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using WhsFacebook.Whs.Logging;
using WhsFacebook.Whs.Service.ErrorReporting;

namespace WhsFacebook.Whs.Service
{
    public partial class WindowsService : ServiceBase
    {
		private readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof(WindowsService));
        private ServiceHost _host;

        static WindowsService()
        {
            LogFactory.Configure("Service");
        }

		public WindowsService()
		{
			try
			{
				InitializeComponent();
			}
			catch (Exception e)
			{
				_log.Fatal("Failed to create service", e);

				throw;
			}
		}

		protected override void OnStart(string[] args)
		{
			_log.Info("OnStart()");

			foreach (var a in args)
				_log.Info("  argument: " + a);

			// trigger starts
			try
			{
                // trigger singletons
				if (UpdateChecker.Instance == null)
					_log.Fatal("No instance: UpdateChecker");

                if (ErrorReportingStats.Instance == null)
                    _log.Fatal("No instance: ErrorReportingStats");

                if (Submitters.SystemInfoSubmitter.Instance == null)
                    _log.Fatal("No instance: SystemInfoSubmitter");

                if (Submitters.AddinsSubmitter.Instance == null)
                    _log.Fatal("No instance: AddinsSubmitter");

                if (Submitters.StorageSubmitter.Instance == null)
                    _log.Fatal("No instance: StorageSubmitter");

                if (Submitters.DisksSubmitter.Instance == null)
                    _log.Fatal("No instance: DisksSubmitter");
            }
			catch (Exception e)
			{
				_log.Fatal("Failed to trigger singletons", e);

				throw;
			}

			// create service
			try
			{
                _host = new ServiceHost(typeof(SingletonService));

                _host.Faulted += new EventHandler(host_Faulted);
                _host.UnknownMessageReceived += new EventHandler<UnknownMessageReceivedEventArgs>(host_UnknownMessageReceived);

                _host.Open();
			}
			catch (Exception e)
			{
				_log.Fatal("Failed to start WCF service", e);

				throw;
			}

			_log.Info("WCF service now listening.");
		}

        private void host_UnknownMessageReceived(object sender, UnknownMessageReceivedEventArgs e)
        {
            _log.Warn("WCF host received unknown message: " + e.Message.ToString());
        }

        private void host_Faulted(object sender, EventArgs e)
        {
            _log.Warn("WCF host faulted");
        }

		protected override void OnStop()
		{
			_log.Info("OnStop()");

			try
			{
                if (_host != null)
                    _host.Close();
			}
			catch (Exception e)
			{
				_log.Error("Failed to stop WCF service", e);
			}
		}
    }
}
